﻿using EasyCore.Caching.Interfaces;
using EasyCore.Extensions;
using Masuit.Tools;
using NewLife.Caching;
using NewLife.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.Caching.Memory
{
    /// <summary>
    /// <inheritdoc cref="IEasyCacheService"/>
    /// 内存缓存
    /// </summary>
    public partial class MemoryCacheService : IEasyCacheService
    {
        public readonly MemoryCache _memoryCache;

        public MemoryCacheService()
        {
            _memoryCache = new MemoryCache();
        }

        #region 普通操作

        /// <inheritdoc/>
        public T Get<T>(string key)
        {
            var data = _memoryCache.Get<string>(key);
            return data.ToObject<T>();
        }

        /// <inheritdoc/>
        public int Remove(params string[] keys)
        {
            return _memoryCache.Remove(keys);
        }

        /// <inheritdoc/>
        public bool Set<T>(string key, T value, int expire = -1)
        {
            return _memoryCache.Set(key, value.ToJson(), expire);
        }

        /// <inheritdoc/>
        public bool Set<T>(string key, T value, TimeSpan expire)
        {
            return _memoryCache.Set(key, value.ToJson(), expire);
        }

        /// <inheritdoc/>
        public bool SetExpire(string key, TimeSpan expire)
        {
            return _memoryCache.SetExpire(key, expire);
        }

        /// <inheritdoc/>
        public TimeSpan GetExpire(string key)
        {
            return _memoryCache.GetExpire(key);
        }

        /// <inheritdoc/>
        public bool ContainsKey(string key)
        {
            return _memoryCache.ContainsKey(key);
        }

        /// <inheritdoc/>
        public void Clear()
        {
            _memoryCache.Clear();
        }

        /// <inheritdoc/>
        public void DelByPattern(string pattern)
        {
            var keys = _memoryCache.Keys.ToList();//获取所有key
            keys.ForEach(it =>
            {
                if (it.Contains(pattern))//如果匹配
                    _memoryCache.Remove(pattern);
            });
        }

        #endregion 普通操作

        #region 集合操作

        /// <inheritdoc/>
        public IDictionary<string, T> GetAll<T>(IEnumerable<string> keys)
        {
            IDictionary<string, T>? result = default;//定义集合
            IDictionary<string, string>? data = _memoryCache.GetAll<string>(keys);//获取数据
            data.ForEach(it =>
            {
                result.Add(it.Key, it.Value.ToObject<T>());//遍历数据,格式化并加到新的数据集合
            });
            return result;
        }

        /// <inheritdoc/>
        public void SetAll<T>(IDictionary<string, T> values, int expire = -1)
        {
            IDictionary<string, string>? result = default;//定义集合
            values.ForEach(it =>
            {
                result.Add(it.Key, it.Value.ToJson());//遍历数据,格式化并加到新的数据集合
            });
            _memoryCache.SetAll(values, expire);
        }

        /// <inheritdoc/>
        public IDictionary<string, T> GetDictionary<T>(string key)
        {
            IDictionary<string, T>? result = default;//定义集合
            var data = _memoryCache.GetDictionary<string>(key);
            data.ForEach(it =>
            {
                result.Add(it.Key, it.Value.ToObject<T>());//遍历数据,格式化并加到新的数据集合
            });
            return result;
        }

        /// <inheritdoc/>
        public IProducerConsumer<T> GetQueue<T>(string key)
        {
            return _memoryCache.GetQueue<T>(key);
        }

        /// <inheritdoc/>
        public IProducerConsumer<T> GetStack<T>(string key)
        {
            return _memoryCache.GetStack<T>(key);
        }

        /// <inheritdoc/>
        public ICollection<T> GetSet<T>(string key)
        {
            return _memoryCache.GetSet<T>(key);
        }

        #endregion 集合操作

        #region 高级操作

        /// <inheritdoc/>
        public bool Add<T>(string key, T value, int expire = -1)
        {
            return _memoryCache.Add(key, value.ToJson(), expire);
        }

        /// <inheritdoc/>
        public IList<T> GetList<T>(string key)
        {
            IList<T> result = default;//定义集合
            var data = _memoryCache.GetList<string>(key);
            data.ForEach(it =>
            {
                result.Add(it.ToObject<T>());//遍历数据,格式化并加到新的数据集合
            });
            return result;
        }

        /// <inheritdoc/>
        public T Replace<T>(string key, T value)
        {
            return _memoryCache.Replace(key, value);
        }

        /// <inheritdoc/>
        public bool TryGetValue<T>(string key, out T value)
        {
            var result = string.Empty;
            _ = _memoryCache.TryGetValue<string>(key, out result);
            value = result.ToObject<T>();
            return value == null;
        }

        /// <inheritdoc/>
        public long Decrement(string key, long value)
        {
            return _memoryCache.Decrement(key, value);
        }

        /// <inheritdoc/>
        public double Decrement(string key, double value)
        {
            return _memoryCache.Decrement(key, value);
        }

        /// <inheritdoc/>
        public long Increment(string key, long value)
        {
            return _memoryCache.Increment(key, value);
        }

        /// <inheritdoc/>
        public double Increment(string key, double value)
        {
            return _memoryCache.Increment(key, value);
        }

        #endregion 高级操作

        #region 事务

        /// <inheritdoc/>
        public int Commit()
        {
            return _memoryCache.Commit();
        }

        /// <inheritdoc/>
        public IDisposable AcquireLock(string key, int msTimeout)
        {
            return _memoryCache.AcquireLock(key, msTimeout);
        }

        /// <inheritdoc/>
        public IDisposable AcquireLock(string key, int msTimeout, int msExpire, bool throwOnFailure)
        {
            return _memoryCache.AcquireLock(key, msTimeout, msExpire, throwOnFailure);
        }

        #endregion 事务
    }
}
